package com.ctsi.offlinesupport.service;

import com.ctsi.commons.util.StringUtil;
import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.id.UUIDGenerator;
import com.ctsi.commons.util.response.Page;
import com.ctsi.flowable.engine.constant.ProcessInstStatus;
import com.ctsi.framework.common.exception.ExceptionFactory;
import com.ctsi.framework.mybatis.support.MybatisGenericDao;
import com.ctsi.offlinesupport.constant.FlowRole;
import com.ctsi.offlinesupport.constant.FlowStatusConstant;
import com.ctsi.offlinesupport.constant.SupportFlowConstant;
import com.ctsi.offlinesupport.dto.ProcessHisDTO;
import com.ctsi.organise.common.api.PersonServiceProxy;
import com.ctsi.organise.common.model.Organise;
import com.ctsi.organise.common.model.Person;
import com.ctsi.supportflow.app.entity.CustomEntity;
import com.ctsi.supportflow.app.entity.ProjectEntity;
import com.ctsi.supportflow.app.entity.SupportInfo;
import com.ctsi.supportflow.app.entity.SupportTask;
import com.ctsi.supportflow.app.vo.ConfirmVO;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: zhangjw
 * @Date: 2018/9/19 09:11
 * @Description:
 */
@Service
public class OfflineSupportService {

    private static final Logger logger = LoggerFactory.getLogger(OfflineSupportService.class);

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private SupportInfoService supportInfoService;
    @Autowired
    private SupportFlowInfoService supportFlowInfoService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private PersonServiceProxy userServiceProxy;
    @Autowired
    private ExceptionFactory exceptionFactory;
    @Autowired
    private SupportTaskService supportTaskService;
    @Autowired
    private SupportUtilService supportUtilService;
    @Autowired
    private SupportMeetRecordService supportMeetRecordService;
    @Autowired
    private MybatisGenericDao dao;
    @Autowired
    private PersonServiceProxy personServiceProxy;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ManagementService managementService;
    @Autowired
    private ProjectEntityService projectEntityService;
    @Autowired
    private CustomEntityService customEntityService;
    @Autowired
    private TimeUtil timeUtil;

    /**
     * 启动流程并接受第一个填报环节
     *
     * @param supportId
     * @param userId
     * @param supportorId
     * @param isReport    是否上报
     */
    @Deprecated
    public void startSupportFlow(String supportId, String userId, String supportorId, Integer isReport) {
        if (isReport == null) {
            isReport = 0;
        }
        // 获取支撑基本信息
        SupportInfo supportInfo = supportInfoService.findSupportInfoById(supportId);
        if (supportInfo.getCurFlowStatus() == FlowStatusConstant.STARTED.value) {
            // 流程已启动，不能重复启动
            exceptionFactory.throwDefinedException("600100", supportInfo.getSupportNum());
        }
        //设置流程发起人
        Authentication.setAuthenticatedUserId(userId);

        // 设置流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put(SupportFlowConstant.Variables.BUSINESSKEY.name, supportId);
        variables.put(SupportFlowConstant.Variables.APPLYUSERID.name, supportInfo.getApplyUserId());
        variables.put(SupportFlowConstant.Variables.ISAUTO.name, supportInfo.getIsAuto());
        variables.put(SupportFlowConstant.Variables.FLOWSTARTTIME.name, System.currentTimeMillis());
        variables.put(SupportFlowConstant.Variables.STANDARD.name, supportInfo.getStandard());
        variables.put(SupportFlowConstant.Variables.SUPPORTNUM.name, supportInfo.getSupportNum());
        variables.put(SupportFlowConstant.Variables.SUPPORTTYPE.name, supportInfo.getSupportType());
        // 设置支撑经理
        variables.put("supportorId", supportorId);
        // TODO: 设置自动派单次数
        variables.put(SupportFlowConstant.Variables.AUTOSENDCOUNT.name, 3);
        // 设置省政支是否直接到人 默认到部门
        variables.put("send2User", 0);
        Organise organ = userServiceProxy.getOrganise4User(supportInfo.getApplyUserId());
        variables.put(SupportFlowConstant.Variables.APPLYUSERORGANID.name, organ.getPartyId());
        // 判断是否是省公司派单
        if (organ.getPartyId().equals("ik1ZbQBP8KB0OOwVokE") || isReport == 1) {
            variables.put(SupportFlowConstant.Variables.ISPROVINCIAL.name, 1);
        } else {
            variables.put(SupportFlowConstant.Variables.ISPROVINCIAL.name, 0);
            // 初始化政支注入派单人
            String leaderId = supportUtilService.findSupportMan(organ.getPartyId());
            variables.put("departLeaderSender", leaderId);
        }
        // 是否上报标记
        variables.put(SupportFlowConstant.Variables.ISREPORTED.name, isReport);
        // 初始化省政支主任人选
        String zhurens = supportUtilService.finRoleMemberRandom(FlowRole.SHENGZHUREN.value);
        variables.put("proLeaderSender", zhurens);
        // 启动流程,返回流程实例
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(SupportFlowConstant.SUPPORT_FLOW_PROCESSID, supportId, variables);
        SupportInfo info = new SupportInfo();
        info.setId(supportId);
        // info.setProcessInstanceId(instance.getProcessInstanceId());
        // 设置流程名称
        runtimeService.setProcessInstanceName(instance.getId(), supportInfo.getCustomName());
        info.setCurFlowStatus(FlowStatusConstant.STARTED.value);

        info.setProcessDefId(instance.getProcessDefinitionId());
        info.setProcessInstId(instance.getProcessInstanceId());
        info.setFlowStartTime(System.currentTimeMillis());
        info.setIsReported(isReport);
        this.supportInfoService.updateSupportInfoByPKSelective(info);

        // 完成第一个环节
        Task selfTask = taskService.createTaskQuery().processInstanceId(instance.getProcessInstanceId()).taskAssignee(userId).singleResult();
        taskService.complete(selfTask.getId());
    }

    /**
     * 填报并启动流程
     *
     * @param supportInfo
     * @param userId
     */
    @Deprecated
    public void insertAndstart(SupportInfo supportInfo, String userId, String supportorId) {
        // 处理项目信息
        String projectId = supportInfo.getCustomGroupId();
        String customId = supportInfo.getCustomName();

        ProjectEntity project = projectEntityService.findProjectEntityById(projectId);
        CustomEntity customEntity = customEntityService.findCustomEntityById(customId);

        if (customEntity == null) {
            customEntity = new CustomEntity();
            customEntity.setCreateTime(System.currentTimeMillis());
            customEntity.setCreateBy(userId);

            customEntity.setId(UUIDGenerator.getId());
            customEntity.setCustomName(customId);

            customEntityService.insertCustomEntity(customEntity);

            supportInfo.setCustomName(customEntity.getId());
        }

        if (project == null) {
            ProjectEntity projectEntity = new ProjectEntity();
            projectEntity.setId(UUIDGenerator.getId());
            projectEntity.setProjectName(projectId);
            projectEntity.setCreateTime(System.currentTimeMillis());
            projectEntity.setCreateBy(userId);
            projectEntity.setCustomId(customEntity.getId());
            projectEntityService.insertProjectEntity(projectEntity);

            supportInfo.setCustomGroupId(project.getId());
        }

        supportInfoService.insertSupportInfo(supportInfo);
        this.startSupportFlow(supportInfo.getId(), userId, supportorId, supportInfo.getIsReported());
    }



    /**
     * 启动流程并接受第一个填报环节
     *
     * @param supportId
     * @param userId
     * @param supportorId
     * @param isReport    是否上报
     */
    public void startSupportFlow2019(String supportId, String userId, String supportorId, Integer isReport) {
        // 获取支撑基本信息
        SupportInfo supportInfo = supportInfoService.findSupportInfoById(supportId);
        if (supportInfo.getCurFlowStatus() == FlowStatusConstant.STARTED.value) {
            // 流程已启动，不能重复启动
            exceptionFactory.throwDefinedException("600100", supportInfo.getSupportNum());
        }
        //设置流程发起人
        Authentication.setAuthenticatedUserId(userId);

        // 设置流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put(SupportFlowConstant.Variables.BUSINESSKEY.name, supportId);
        variables.put(SupportFlowConstant.Variables.APPLYUSERID.name, supportInfo.getApplyUserId());
        variables.put(SupportFlowConstant.Variables.ISAUTO.name, supportInfo.getIsAuto());
        variables.put(SupportFlowConstant.Variables.FLOWSTARTTIME.name, System.currentTimeMillis());
        variables.put(SupportFlowConstant.Variables.STANDARD.name, supportInfo.getStandard());
        variables.put(SupportFlowConstant.Variables.SUPPORTNUM.name, supportInfo.getSupportNum());
        variables.put(SupportFlowConstant.Variables.SUPPORTTYPE.name, supportInfo.getSupportType());
        // 设置支撑经理
        //        variables.put("supportorId", supportorId);
        // TODO: 设置自动派单次数
        variables.put(SupportFlowConstant.Variables.AUTOSENDCOUNT.name, 3);
        // 设置省政支是否直接到人 默认到部门
        variables.put("send2User", 0);
        Organise organ = userServiceProxy.getOrganise4User(supportInfo.getApplyUserId());
        variables.put(SupportFlowConstant.Variables.APPLYUSERORGANID.name, organ.getPartyId());
        // 判断来源是地市还是省里的
        if (supportUtilService.isProvice(userId) || isReport == 1) {
            variables.put("proLeaderSender", supportorId); // 云网派单
            variables.put(SupportFlowConstant.Variables.ISPROVINCIAL.name, 1);
        } else {
            variables.put(SupportFlowConstant.Variables.ISPROVINCIAL.name, 0);
            variables.put("departLeaderSender", supportorId);
        }
        // 是否上报标记
        variables.put(SupportFlowConstant.Variables.ISREPORTED.name, isReport);
        // 启动流程,返回流程实例
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(SupportFlowConstant.SUPPORT_FLOW_PROCESSID, supportId, variables);
        SupportInfo info = new SupportInfo();
        info.setId(supportId);
        // 设置流程名称
        runtimeService.setProcessInstanceName(instance.getId(), supportInfo.getCustomName());
        info.setCurFlowStatus(FlowStatusConstant.STARTED.value);

        info.setProcessDefId(instance.getProcessDefinitionId());
        info.setProcessInstId(instance.getProcessInstanceId());
        info.setFlowStartTime(System.currentTimeMillis());
        info.setIsReported(isReport);
        this.supportInfoService.updateSupportInfoByPKSelective(info);
        // 完成第一个环节
        Task selfTask = taskService.createTaskQuery().processInstanceId(instance.getProcessInstanceId()).taskAssignee(userId).singleResult();
        taskService.complete(selfTask.getId());
    }

    /**
     * 填报并启动流程
     * @param supportInfo
     * @param userId
     * @param supportorId
     */
    public void insertAndstart2019(SupportInfo supportInfo, String userId, String supportorId) {
        // 处理项目信息
        String projectId = supportInfo.getCustomGroupId();
        String customId = supportInfo.getCustomName();

        ProjectEntity project = projectEntityService.findProjectEntityById(projectId);
        CustomEntity customEntity = customEntityService.findCustomEntityById(customId);

        if (customEntity == null) {
            customEntity = new CustomEntity();
            customEntity.setCreateTime(System.currentTimeMillis());
            customEntity.setCreateBy(userId);

            customEntity.setId(UUIDGenerator.getId());
            customEntity.setCustomName(customId);

            customEntityService.insertCustomEntity(customEntity);

            supportInfo.setCustomName(customEntity.getId());
        }

        if (project == null) {
            ProjectEntity projectEntity = new ProjectEntity();
            projectEntity.setId(UUIDGenerator.getId());
            projectEntity.setProjectName(projectId);
            projectEntity.setCreateTime(System.currentTimeMillis());
            projectEntity.setCreateBy(userId);
            projectEntity.setCustomId(customEntity.getId());
            projectEntityService.insertProjectEntity(projectEntity);

            supportInfo.setCustomGroupId(project.getId());
        }

        supportInfoService.insertSupportInfo(supportInfo);
        this.startSupportFlow2019(supportInfo.getId(), userId, supportorId, supportInfo.getIsReported());
    }





//    /**
//     * 查询个人已办理任务
//     *
//     * @param userId
//     * @return
//     */
//    public List<HistoricTaskInstance> historyTasks(String userId) {
//        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery().
//                processDefinitionKey(SupportFlowConstant.SUPPORT_FLOW_PROCESSID)
//                .taskAssignee(userId).or().taskCandidateUser(userId).finished().orderByHistoricTaskInstanceEndTime().desc().list();
//        return tasks;
//    }

    /**
     * 待办列表
     *
     * @param userId
     */
    public Page<Task> agendaTasks(String userId, int start, int pageSize) {
        TaskQuery query = taskService.createTaskQuery()
                .processDefinitionKey(SupportFlowConstant.SUPPORT_FLOW_PROCESSID)
                .taskAssignee(userId);
        long count = query.count();
        if (count != 0L) {
            List<Task> tasks = query.orderByTaskCreateTime().desc().listPage(start, pageSize);
            return new Page<>(new Long(start), count, pageSize, tasks);
        }
        return new Page<>(new Long(start), count, pageSize, Collections.emptyList());
    }

    /**
     * 领取任务
     *
     * @param userId
     */
    public Task claim(String taskId, String userId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task.getClaimTime() == null) {
            return task;
        }
        taskService.claim(taskId, userId);
        return task;
    }

    /**
     * 签收，指定下环节处理人，并完成本环节
     *
     * @param userId
     * @param expression
     * @param assigns
     * @param comment    备注信息
     */
    public void claimAndComplete(String userId, String taskId, String expression, String comment, String... assigns) {
        if (UtilValidate.isEmpty(assigns)) {
            exceptionFactory.throwDefinedException("600101");
        }
        Task task = this.claim(taskId, userId);
        Map<String, Object> vars = new HashMap<>();
        vars.put(expression, Arrays.asList(assigns));
        if (UtilValidate.isNotEmpty(comment)) {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
        }
        taskService.complete(task.getId(), vars);
    }

    /**
     * @param userId
     * @param taskId
     * @param expression
     * @param comment
     * @param assigns
     */
    public void claimAndComplete(String userId, String taskId, String expression, String comment, String assigns) {
        if (UtilValidate.isEmpty(assigns)) {
            exceptionFactory.throwDefinedException("600101");
        }
        Task task = this.claim(taskId, userId);
        Map<String, Object> vars = new HashMap<>();
        vars.put("send2User", 0);
        vars.put(expression, assigns);
        if (UtilValidate.isNotEmpty(comment)) {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
        }
        taskService.complete(task.getId(), vars);
    }

    /**
     * 上报 转办
     *
     * @param taskId
     * @param comment
     */
    public void report(String taskId, String curUserId, String comment) {
        Task task = this.claim(taskId, curUserId);
        String processInstId = task.getProcessInstanceId();
        SupportInfo supportInfo = this.supportInfoService.findSupportInfoByProcessInstId(processInstId, curUserId);
        SupportInfo temp = new SupportInfo();
        temp.setId(supportInfo.getId());
        // 更新流程状态
        temp.setIsReported(1);
        this.supportInfoService.updateSupportInfoByPKSelective(temp);
        if (UtilValidate.isNotEmpty(comment)) {
            Authentication.setAuthenticatedUserId(curUserId);
            taskService.addComment(taskId, processInstId, comment);
        }
        taskService.setVariable(taskId, SupportFlowConstant.Variables.ISREPORTED.name, 1);
        //taskService.setOwner(taskId,curUserId); //设置owner，方便查询
        //taskService.setAssignee(taskId, targetUserId);
        taskService.complete(taskId);
    }

    /**
     * 增派单
     *
     * @param taskId    任务ID
     * @param comment   备注
     * @param curUserId 当前登陆用户ID
     * @param assigns   增派人员
     */
    public void fill(String taskId, String comment, String curUserId, String... assigns) {
        if (UtilValidate.isEmpty(assigns)) {
            exceptionFactory.throwDefinedException("600102");
        }
        String executionId = isCanFill(taskId);
        if (UtilValidate.isEmpty(executionId)) {
            exceptionFactory.throwDefinedException("600105");
        }
//        HistoricTaskInstance htask = historyService.createHistoricTaskInstanceQuery().executionId(executionId).singleResult();
        /**
         * 获取环节参与者进行过滤
         */
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(executionId).taskDefinitionKey("supporting").list();
        Set<String> users = tasks.stream().map(t -> t.getAssignee()).collect(Collectors.toSet());
        if (UtilValidate.isNotEmpty(users)) {
            for (String assign : assigns) {
                if (!users.contains(assign)) {
                    Map<String, Object> vars = new HashMap<>();
                    vars.put("supportUserList", Arrays.asList(assign));
                    vars.put("supportUsers", StringUtil.join(Arrays.asList(assign), ","));
                    runtimeService.addMultiInstanceExecution("supporting", executionId, vars);
                }
            }
        }
//        if (UtilValidate.isNotEmpty(comment)) {
//            Authentication.setAuthenticatedUserId(curUserId);
//            taskService.addComment(taskId, htask.getProcessInstanceId(), comment);
//        }
    }

    /**
     * 是否可以增派单子
     *
     * @param taskId
     * @return
     */
    public String isCanFill(String taskId) {
        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        // 历史该审批节点
//        String curActivitiId = task.getTaskDefinitionKey();
        ExecutionEntity entity = managementService.executeCommand(commandContext -> {
            ExecutionEntityManager manager = CommandContextUtil.getExecutionEntityManager(commandContext);
            return searchForMultiInstanceActivity("supporting", task.getProcessInstanceId(), manager);
        });
        if (entity != null) {
            return entity.getParentId();
        }
//        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
//        // 历史该节点
//        Activity flowNode = (Activity) bpmnModel.getFlowElement(curActivitiId);
//        Set<Activity> destActivitis = getDestActivitis(flowNode);
//        if (UtilValidate.isEmpty(destActivitis) || destActivitis.size() != 1) {
//            return null;
//        }
//        Activity targerFlow = destActivitis.stream().findAny().get();
//        // 判断该多实例环节是否结束
//       // Execution ee = runtimeService.createExecutionQuery().activityId(targerFlow.getId()).singleResult();
//        Task targerTask = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).taskDefinitionKey(targerFlow.getId()).list().stream().findAny().get();
//        if (targerTask != null) {
//            return targerTask.getExecutionId();
//        }
        return null;
    }
//    /**
//     * 获取该节点的所有直接多实例任务节点
//     * @param curActivity
//     * @return
//     */
//    private Set<Activity> getDestActivitis(FlowNode curActivity) {
//        List<SequenceFlow> flows = curActivity.getOutgoingFlows();
//        Set<Activity> srcs = new HashSet<>();
//        for (SequenceFlow flow : flows) {
//            /**
//             * 此处可以肯定 返回类型肯定是flowNode类型
//             */
//            FlowNode node = (FlowNode) flow.getTargetFlowElement();
//            /**
//             * 注意只要多实例节点
//             */
//            if (node.getBehavior() instanceof MultiInstanceActivityBehavior) {
//                //任务节点
//                srcs.add((Activity) node);
//            }
//            if (node.getBehavior() instanceof GatewayActivityBehavior) {
//                // 网关节点
//                srcs.addAll(getDestActivitis(node));
//            }
//        }
//        return srcs;
//    }

    /**
     * 根据父执行ID，查找多实例子执行ID
     *
     * @param activityId
     * @param parentExecutionId
     * @param executionEntityManager
     * @return
     */
    private ExecutionEntity searchForMultiInstanceActivity(String activityId, String parentExecutionId, ExecutionEntityManager executionEntityManager) {
        List<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(parentExecutionId);
        ExecutionEntity miExecution = null;
        for (ExecutionEntity childExecution : childExecutions) {
            if (activityId.equals(childExecution.getActivityId()) && childExecution.isMultiInstanceRoot()) {
                if (miExecution != null) {
                    logger.error("Multiple multi instance executions found for activity id " + activityId);
                    return null;
                }
                miExecution = childExecution;
            }
            ExecutionEntity childMiExecution = searchForMultiInstanceActivity(activityId, childExecution.getId(), executionEntityManager);
            if (childMiExecution != null) {
                if (miExecution != null) {
                    logger.error("Multiple multi instance executions found for activity id " + activityId);
                    return null;
                }
                miExecution = childMiExecution;
            }
        }
        return miExecution;
    }

    /**
     * 申请协同
     *
     * @param taskId
     * @param curUserId
     */
    public void applyFill(String taskId, String curUserId) {
        Task task = this.claim(taskId, curUserId);
        Map<String, Object> param = new HashMap<>();
        param.put("assistLeader", curUserId);
        param.put(SupportFlowConstant.Variables.BUSINESSKEY.name, taskService.getVariable(taskId, SupportFlowConstant.Variables.BUSINESSKEY.name));
        Execution execution = runtimeService.createExecutionQuery()
                .processInstanceId(task.getProcessInstanceId())
                .messageEventSubscriptionName("applyAsster").singleResult();
        runtimeService.messageEventReceived("applyAsster", execution.getId(), param);
    }

    /**
     * 支撑人员接单
     *
     * @param taskId
     * @param curUserId
     */
    public Task supportorCliam(String taskId, String curUserId) {
        Task task = this.claim(taskId, curUserId);
        // 接单变量
        taskService.setVariable(taskId, "approve", true);
        this.insertSupportTask(taskId, curUserId, 1, 0);
        return task;
    }

    /**
     * 专家接单
     *
     * @param taskId
     * @param curUserId
     */
    public void assterCliam(String taskId, String curUserId) {
        this.insertSupportTask(taskId, curUserId, 2, 0);
    }

    /**
     * 获取环节操作按钮
     *
     * @param actId
     * @param taskId
     * @param curUserId
     * @return
     */
    public Set<String> getActions(String actId, String taskId, String curUserId) {

        Set<String> actions = new HashSet<>();
        if ("submit-support-form".equals(actId)) {
            actions.add("deleteSupportOrder");// 撤单
            actions.add("restartSupportOrder");// 发起支撑
            actions.add("editSupportOrder"); // 编辑支撑单
        } else if ("provincial-send-activity".equals(actId)) {

            actions.add("organLeaderSend2User"); //发送给支撑经理
            actions.add("organLeaderSend2Depart"); // 发送到部门负责人
            actions.add("leaderBack");

        } else if ("city-send-activity".equals(actId)) {

            // 地市政支主任
            actions.add("leaderSend2User");
            actions.add("leaderSend2Depart");
            actions.add("leaderBack");

        } else if ("depart-role-send-activity".equals(actId)) {
            actions.add("departSend"); // 部门派单,发送给人
            actions.add("departBack"); // 部门派单人退回
        } else if ("supporting".equals(actId)) {
            // 接单
            SupportTask stask = supportTaskService.findSupportTaskByUser(taskId, curUserId);

            if (stask == null) {
                actions.add("supportorReceiving");
                //actions.add("supportorRefuse");
            } else {
                actions.add("supportorApplyFill");
                actions.add("supportorMeetingRecord");
                //actions.add("supportorBack");
                actions.add("supportorComplete");
            }
            actions.add("supportorBack");

        } else if ("initor-confirm".equals(actId)) {

            actions.add("confirmComplete");

        } else if ("assertLeader-activity".equals(actId)) {

            actions.add("assertLeaderSend");
            actions.add("assistorBack");
        } else if ("sid-CB0BCB31-C0E7-4363-A073-6D6130AE0B74".equals(actId)) {
            SupportTask stask = supportTaskService.findSupportTaskByUser(taskId, curUserId);

            if (stask == null) {
                actions.add("assistorReceiving");
            } else {
//                    actions.add("supportorMeetingRecord");
                actions.add("assistorComplete");
            }
            actions.add("assistorBack");
        }
        return actions;
    }

    /**
     * 政支主任派单
     *
     * @param taskId
     * @param targetUserIds
     * @param comment
     */
    public void leaderSend2User(String taskId, String curUserId, String[] targetUserIds, String comment) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 处理上报流程变量
        taskService.setVariable(taskId, SupportFlowConstant.Variables.ISREPORTED.name, 0);
        Map<String, Object> vars = new HashMap<>();
        // 判断用户是否是接口人
        boolean isDepart = this.isRoleUser(FlowRole.DEPART.value, targetUserIds[0]);
        if (isDepart) {
            if (targetUserIds.length > 1) {
                exceptionFactory.throwDefinedException("600104");
            }
            vars.put("send2User", 0);
            vars.put("departSender", targetUserIds[0]);
        } else {
            vars.put("send2User", 1);
            vars.put("supportUsers", StringUtil.join(Arrays.asList(targetUserIds), ","));
            vars.put("supportUserList", Arrays.asList(targetUserIds));
        }
        if (UtilValidate.isNotEmpty(comment)) {
            Authentication.setAuthenticatedUserId(curUserId);
            taskService.addComment(taskId, task.getProcessInstanceId(), comment);
        }
        /**
         * 为了统计派单及时率
         */
        this.insertSupportTask(taskId, curUserId, 3, 2);
        taskService.complete(task.getId(), vars);
    }

    /**
     * 协同负责人派单
     *
     * @param taskId
     * @param curUserId
     * @param targetUserIds
     * @param comment
     */
    public void assterLeaderSend2User(String taskId, String curUserId, String[] targetUserIds, String comment) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String, Object> vars = new HashMap<>();
        List<String> ids = Arrays.asList(targetUserIds);
        vars.put("assister", StringUtil.join(ids, ","));
        vars.put("assisterList", ids);

        if (UtilValidate.isNotEmpty(comment)) {
            Authentication.setAuthenticatedUserId(curUserId);
            taskService.addComment(taskId, task.getProcessInstanceId(), comment);
        }
        taskService.complete(task.getId(), vars);
    }

    /**
     * 支撑经理完成任务
     *
     * @param workLoad
     * @param taskId
     * @param adjunctId
     * @param confirmVOS
     */
    public void supportorComplete(Double workLoad, String taskId, String adjunctId, List<ConfirmVO> confirmVOS) {

        // 评价支撑专家
        this.supportEval(confirmVOS);
        this.supportComplete(workLoad, taskId, adjunctId);
    }

    public void supportComplete(Double workLoad, String taskId, String adjunctId) {
        // TODO: 处理附件
        SupportTask supportTask = new SupportTask();
        supportTask.setTaskStatus(2);
        supportTask.setOriginalWorkLoad(new BigDecimal(workLoad));
        supportTask.setWorkLoad(new BigDecimal(workLoad));
        supportTask.setOriginalWorkLoad(new BigDecimal(workLoad));
        supportTask.setTaskId(taskId);

        this.supportTaskService.updateSupportTaskByPKSelective(supportTask);
        taskService.complete(taskId);
    }

//    /**
//     * 支撑经理评价环节
//     * @param confirmVOS
//     */
//    public void supportorEval(List<ConfirmVO> confirmVOS){
//        confirmVOS.forEach(vo -> {
//            String taskId = vo.getSupportTaskId();
//            SupportTask supportTask = new SupportTask();
//            supportTask.setTaskId(taskId);
//            supportTask.setWorkLoad(new BigDecimal(vo.getWorkLoad()));
//            supportTask.setEvalContent(vo.getEvalContent());
//            supportTask.setEvalScore(vo.getServiceScore());
//            this.supportTaskService.updateSupportTaskByPKSelective(supportTask);
//        });
//    }

    /**
     * 评价支撑专家
     *
     * @param confirmVOS
     */
    public void supportEval(List<ConfirmVO> confirmVOS) {
        confirmVOS.stream().forEach(vo -> {
            SupportTask task = new SupportTask();
            task.setTaskId(vo.getSupportTaskId());
            task.setEvalScore(vo.getServiceScore());
            task.setEvalContent(vo.getEvalContent());
            supportTaskService.updateSupportTaskByPKSelective(task);
        });
    }

    /**
     * 客户经理办结
     *
     * @param taskId
     * @param confirmVOS
     */
    public void confirmComplete(String taskId, List<ConfirmVO> confirmVOS) {
        this.confirmEval(confirmVOS);
        this.confirmComplete(taskId);
    }

    public void confirmComplete(String taskId) {
        // TODO: 更新主表状态，结束子流程
        String id = (String) taskService.getVariable(taskId, SupportFlowConstant.Variables.BUSINESSKEY.name);
        SupportInfo info = new SupportInfo();
        info.setId(id);
        //设置完成状态
        info.setCurFlowStatus(FlowStatusConstant.COMPLETE.value);
        info.setFlowOverTime(System.currentTimeMillis());
        supportInfoService.updateSupportInfoByPKSelective(info);
        taskService.complete(taskId);
    }

    public void confirmEval(List<ConfirmVO> confirmVOS) {
        confirmVOS.forEach(vo -> {
            String _taskId = vo.getSupportTaskId();
            SupportTask supportTask = new SupportTask();
            supportTask.setTaskId(_taskId);
            supportTask.setWorkLoad(new BigDecimal(vo.getWorkLoad()));
            supportTask.setEvalContent(vo.getEvalContent());
            supportTask.setEvalScore(vo.getServiceScore());
            this.supportTaskService.updateSupportTaskByPKSelective(supportTask);
        });
    }

    /**
     * 撤单
     *
     * @param taskId
     */
    public void delFlow(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 更新支撑单状态
        String id = (String) taskService.getVariable(taskId, SupportFlowConstant.Variables.BUSINESSKEY.name);
        SupportInfo info = supportInfoService.findSupportInfoById(id);
        SupportInfo temp = new SupportInfo();
        temp.setId(info.getId());
        temp.setCurFlowStatus(FlowStatusConstant.DELETE.value);
        supportInfoService.updateSupportInfoByPKSelective(temp);
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(), ProcessInstStatus.REVOKE);
    }

//    /**
//     * 部门派单人退回
//     *
//     * @param taskId
//     * @param comment
//     */
//    @Deprecated
//    public void departBack(String taskId, String comment) {
//        int isReported = (int) taskService.getVariable(taskId, SupportFlowConstant.Variables.ISREPORTED.name);
//        if (isReported == 1) {
//
//        } else {
//            this.SupportorBack(taskId, "leader-send-order", comment);
//        }
//    }

    /**
     * 发起人重新提交支撑单
     *
     * @param taskId
     * @param comment
     */
    public void applyUserSendSupport(String taskId, String comment) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (UtilValidate.isNotEmpty(comment)) {
            taskService.addComment(taskId, task.getProcessInstanceId(), comment);
        }
        taskService.complete(taskId);
    }

    @Deprecated
    public List<Map<String, Object>> getHis(String processInstId) {
        return (List<Map<String, Object>>) dao.queryForList(SupportInfo.class.getName() + ".processHis", processInstId);
    }

    /**
     * 获取流转历史
     *
     * @param processInstId
     * @return
     */
    public List<ProcessHisDTO> getHisRecord(String processInstId) {
        return (List<ProcessHisDTO>) dao.queryForList(SupportInfo.class.getName() + ".processHisRecord", processInstId);
    }

    /**
     * 插入子表单任务数据
     *
     * @param taskId
     * @param curUserId
     * @param userRoleType
     * @param taskStatus
     */
    private void insertSupportTask(String taskId, String curUserId, Integer userRoleType, Integer taskStatus) {
//        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();

        SupportTask supportTask = new SupportTask();
        supportTask.setTaskId(taskId);
        supportTask.setTaskStatus(taskStatus);
        supportTask.setUserRoleType(userRoleType);
        supportTask.setBusinessKey((String) taskService.getVariable(taskId, SupportFlowConstant.Variables.BUSINESSKEY.name));
        supportTask.setProcessInstId(task.getProcessInstanceId());
        supportTask.setSupportUserId(curUserId);

        Person person = personServiceProxy.findPersonById(curUserId);

        supportTask.setSupportUserMail(person.getEmail());
        supportTask.setSupportUserName(person.getFullName());
        supportTask.setDataObjectId(person.getDataObjectId());

        Organise depart = personServiceProxy.getDepart4User(curUserId);
        Organise organ = personServiceProxy.getOrganise4User(curUserId);
        supportTask.setSupportOrganChainName(personServiceProxy.getPesonAsc(curUserId).stream().map(o -> o.getPartyName()).collect(Collectors.joining(">")));
        supportTask.setSupportorOrganId(organ.getPartyId());
        supportTask.setSupportDepartId(depart.getPartyId());

        supportTask.setSupportorOrganName(organ.getOrganiseName());
        supportTask.setSupportorDepartName(depart.getOrganiseName());

        /**
         * 处理接单及时率
         */
        Long curTime = System.currentTimeMillis();
        supportTask.setApplyTime(curTime);
//        long createTime = task.getStartTime().getTime();
        supportTask.setLastHandlerTime(timeUtil.getLastHandlerTime(task.getStartTime(), 60));
        if (curTime > supportTask.getLastHandlerTime()) {
            supportTask.setTimely(0);
        } else {
            supportTask.setTimely(1);
        }
        this.supportTaskService.insertSupportTask(supportTask);
    }

    /**
     * 判断是否是指定角色用户
     *
     * @param roleType
     * @param userId
     * @return
     */
    public boolean isRoleUser(String roleType, String userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("roleType", roleType);
        params.put("userId", userId);

        long count = (long) dao.queryForObject(SupportInfo.class.getName() + ".findRolesByUserId", params);
        return count > 0;
    }

    /**
     * 协助专家完成任务
     *
     * @param userId
     * @param taskId
     * @param workLoad
     * @param plan
     */
    public void assertComplate(String userId, String taskId, double workLoad, String plan) {
        SupportTask tem = new SupportTask();
        tem.setTaskStatus(2);
        tem.setTaskId(taskId);

        tem.setWorkLoad(new BigDecimal(workLoad));
        tem.setOriginalWorkLoad(new BigDecimal(workLoad));
        tem.setSupportContent(plan);
        tem.setTaskStatus(2);
        supportTaskService.updateSupportTaskByPKSelective(tem);
        taskService.setVariable(taskId, "assistBack", 0);
        taskService.complete(taskId);
    }

}
